//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.tuiofx.internal.gesture;

import java.awt.*;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.animation.Animation.Status;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventTarget;
import javafx.scene.Node;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.PickResult;
import javafx.util.Duration;
import org.tuiofx.internal.util.LogUtils;
import org.tuiofx.internal.util.Util;

public class LongPressDetector {
    private final long longPressDuration;
    private final int requiredNumberOfTouches = 1;
    private Timeline longPressTimer;
    private Map<EventTarget, ClickCounter> counters = new HashMap<>();
    private SimpleBooleanProperty longpressDetected = new SimpleBooleanProperty(false);
    private boolean hasMouseReleaseRequiredTouchPoints;
    private TuioTouchPoint longPressTouchPoint;
    private Deque<TuioTouchPoint> touchPointsMoveQueue;
    private int touchPointsCount;

    public LongPressDetector(long longPressDuration) {
        this.longPressDuration = longPressDuration;
        this.createLongpressTimeline();
    }

    public TuioTouchPoint getLongPressTouchPoint() {
        return this.longPressTouchPoint;
    }

    private Timeline createLongpressTimeline() {
        this.longPressTimer = new Timeline(new KeyFrame[]{new KeyFrame(new Duration((double) this.longPressDuration), new EventHandler<ActionEvent>() {
            public void handle(ActionEvent event) {
                if (LongPressDetector.this.touchPointsCount == 1) {
                    ClickCounter counter = (ClickCounter) LongPressDetector.this.counters.get(LongPressDetector.this.longPressTouchPoint.getTargetNode());
                    if (counter.isStill()) {
                        LongPressDetector.this.longpressDetected.setValue(true);
                    } else {
                        LongPressDetector.this.longpressDetected.setValue(false);
                    }
                }

            }
        }, new KeyValue[0])});
        this.longPressTimer.setCycleCount(1);
        return this.longPressTimer;
    }

    private ClickCounter createClickCounter(Node targetNode) {
        ClickCounter counter = (ClickCounter) this.counters.get(targetNode);
        if (counter == null) {
            counter = new ClickCounter();
            this.counters.put(targetNode, counter);
        }

        return counter;
    }

    public void touchesBegan(TuioTouchPoint touchPoint) {
        ++this.touchPointsCount;
        if (this.touchPointsCount > 1) {
            if (this.isRunning()) {
                this.longPressTimer.stop();
            }

            this.longpressDetected.setValue(false);
        } else {
            if (this.touchPointsCount == 1) {
                this.longpressDetected.setValue(false);
                this.longPressTouchPoint = touchPoint;
                ClickCounter counter = this.createClickCounter((Node) touchPoint.getTargetNode());
                counter.start(touchPoint.getSceneX(), touchPoint.getSceneY());
                if (this.isRunning()) {
                    LogUtils.error("FATAL: should not running");
                }

                this.longPressTimer.play();
            }

        }
    }

    public Timeline getTimeline() {
        return this.longPressTimer;
    }

    public SimpleBooleanProperty getLongpressDetected() {
        return this.longpressDetected;
    }

    public void touchesMove(TuioTouchPoint touchPoint) {
        if (this.longPressTouchPoint.equals(touchPoint)) {
            ClickCounter counter = (ClickCounter) this.counters.get(touchPoint.getTargetNode());
            if (counter != null) {
                counter.moved(touchPoint.getSceneX(), touchPoint.getSceneY());
                if (this.isRunning() && !counter.isStill()) {
                    this.longpressDetected.setValue(false);
                    this.longPressTimer.stop();
                }

            }
        }
    }

    public boolean isRunning() {
        return this.longPressTimer.getStatus().equals(Status.RUNNING);
    }

    public void touchesEnd(TuioTouchPoint touchPoint) {
        --this.touchPointsCount;
        if (this.isRunning() && this.touchPointsCount == 0) {
            this.longpressDetected.setValue(false);
            this.longPressTimer.stop();
        }

    }

    protected void fireContextEventMenu(final TuioTouchPoint touchPoint) {
        Platform.runLater(new Runnable() {
            public void run() {
                LogUtils.debug("FIRE context menu");
                EventTarget eventTarget = touchPoint.getTargetNode();
                boolean isKeyboardTrigger = false;
                PickResult pickResult = new PickResult(eventTarget, touchPoint.getSceneX(), touchPoint.getSceneY());
                ContextMenuEvent context = new ContextMenuEvent(ContextMenuEvent.CONTEXT_MENU_REQUESTED, touchPoint.getSceneX(), touchPoint.getSceneY(), touchPoint.getScreenX(), touchPoint.getScreenY(), isKeyboardTrigger, pickResult);
                Event.fireEvent(eventTarget, context);
            }
        });
    }

    private static class ClickCounter {
        private int clickCount;
        Toolkit toolkit;
        private Timeline timeout;
        private boolean timeoutIsReached;
        private boolean still;
        private double pressedX;
        private double pressedY;

        private ClickCounter() {
            this.clickCount = 0;
            this.toolkit = Toolkit.getDefaultToolkit();
        }

        int incrementClickCount() {
            return this.clickCount++;
        }

        boolean isTimeoutReached() {
            return this.timeoutIsReached;
        }

        private boolean isStill() {
            return this.still;
        }

        int getClickCount() {
            return this.clickCount;
        }

        private void clear() {
            this.clickCount = 0;
        }

        private void out() {
            this.timeoutIsReached = true;
            this.stopTimeout();
        }

        private void moved(final double x, final double y) {
            Platform.runLater(new Runnable() {
                public void run() {
                    if (Math.abs(x - ClickCounter.this.pressedX) > 10.0 || Math.abs(y - ClickCounter.this.pressedY) > 10.0) {
                        ClickCounter.this.out();
                        ClickCounter.this.still = false;
                    }

                }
            });
        }

        private void start(double x, double y) {
            this.pressedX = x;
            this.pressedY = y;
            if (this.timeoutIsReached) {
                this.clear();
            }

            this.timeoutIsReached = false;
            ++this.clickCount;
            if (this.timeout != null) {
                this.timeout.stop();
            }

            Platform.runLater(new Runnable() {
                public void run() {
                    ClickCounter.this.timeout = new Timeline();
                    ClickCounter.this.timeout.getKeyFrames().add(new KeyFrame(new Duration(Util.getToolkitMultiClickInterval(toolkit)), new EventHandler<ActionEvent>() {
                        public void handle(ActionEvent event) {
                            ClickCounter.this.timeoutIsReached = true;
                            ClickCounter.this.timeout = null;
                        }
                    }, new KeyValue[0]));
                    ClickCounter.this.timeout.play();
                }
            });
            this.still = true;
        }

        private void stopTimeout() {
            if (this.timeout != null) {
                this.timeout.stop();
            }

            this.timeout = null;
        }
    }
}
